package cn.iocoder.yudao.module.reading.controller.app.classes;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
import cn.iocoder.yudao.module.reading.controller.app.classes.vo.*;
import cn.iocoder.yudao.module.reading.controller.app.punch.vo.PunchRecordRespVO;
import cn.iocoder.yudao.module.reading.service.classes.ClassService;
import cn.iocoder.yudao.module.reading.service.assignment.AssignmentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import java.util.ArrayList;
import java.util.List;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

/**
 * 用户 APP - 班级管理
 *
 * @author 芋道源码
 */
@Tag(name = "用户 APP - 班级管理")
@RestController("readingClassController")
@RequestMapping("/reading/classes")
@Validated
@Slf4j
public class ClassController {

    @Resource
    private ClassService classService;
    @Resource
    private AssignmentService assignmentService;

    @GetMapping("/user")
    @Operation(summary = "获取用户班级列表")
    @PreAuthenticated
    public CommonResult<List<ClassRespVO>> getUserClasses() {
        Long userId = getLoginUserId();
        log.info("获取用户班级列表，用户ID: {}", userId);

        List<ClassRespVO> result = classService.getUserClasses(userId);
        return success(result);
    }

    @GetMapping("/{classId}")
    @Operation(summary = "获取班级详细信息")
    @PreAuthenticated
    public CommonResult<ClassRespVO> getClassDetail(
            @Parameter(description = "班级ID", required = true, example = "1") @PathVariable("classId") Long classId) {
        Long userId = getLoginUserId();
        log.info("获取班级详情，班级ID: {}, 用户ID: {}", classId, userId);

        ClassRespVO result = classService.getClassDetail(classId, userId);
        return success(result);
    }

    @PostMapping("")
    @Operation(summary = "创建班级")
    @PreAuthenticated
    public CommonResult<Long> createClass(@Valid @RequestBody ClassCreateReqVO createReqVO) {
        Long userId = getLoginUserId();
        log.info("创建班级，用户ID: {}, 请求参数: {}", userId, createReqVO);

        Long classId = classService.createClass(userId, createReqVO);
        return success(classId);
    }

    @PostMapping("/join")
    @Operation(summary = "加入班级")
    @PreAuthenticated
    public CommonResult<Long> joinClass(@Valid @RequestBody JoinClassReqVO joinReqVO) {
        Long userId = getLoginUserId();
        log.info("加入班级，用户ID: {}, 班级口令: {}", userId, joinReqVO.getClassCode());

        Long classId = classService.joinClass(userId, joinReqVO);
        return success(classId);
    }

    @PutMapping("/{classId}")
    @Operation(summary = "修改班级信息")
    @PreAuthenticated
    public CommonResult<String> updateClass(
            @Parameter(description = "班级ID", required = true, example = "1") @PathVariable("classId") Long classId,
            @Valid @RequestBody ClassUpdateReqVO updateReqVO) {
        Long userId = getLoginUserId();
        log.info("修改班级信息，班级ID: {}, 用户ID: {}, 请求参数: {}", classId, userId, updateReqVO);

        classService.updateClass(classId, userId, updateReqVO);
        return success("班级信息修改成功");
    }

    @DeleteMapping("/{classId}")
    @Operation(summary = "删除班级")
    @PreAuthenticated
    public CommonResult<String> deleteClass(
            @Parameter(description = "班级ID", required = true, example = "1") @PathVariable("classId") Long classId) {
        Long userId = getLoginUserId();
        log.info("删除班级，班级ID: {}, 用户ID: {}", classId, userId);

        classService.deleteClass(classId, userId);
        return success("班级删除成功");
    }

    @GetMapping("/{classId}/members")
    @Operation(summary = "获取班级成员列表（包括老师）")
    @PreAuthenticated
    public CommonResult<List<ClassMemberRespVO>> getClassMembers(
            @Parameter(description = "班级ID", required = true, example = "1") @PathVariable("classId") Long classId) {
        Long userId = getLoginUserId();
        log.info("获取班级成员列表，班级ID: {}, 用户ID: {}", classId, userId);

        List<ClassMemberRespVO> result = classService.getClassMembers(classId, userId);
        return success(result);
    }

    @GetMapping("/{classId}/students")
    @Operation(summary = "获取班级学生列表（排除老师，用于打卡等功能）")
    @PreAuthenticated
    public CommonResult<List<ClassMemberRespVO>> getClassStudents(
            @Parameter(description = "班级ID", required = true, example = "1") @PathVariable("classId") Long classId) {
        Long userId = getLoginUserId();
        log.info("获取班级学生列表，班级ID: {}, 用户ID: {}", classId, userId);

        List<ClassMemberRespVO> result = classService.getClassStudents(classId, userId);
        return success(result);
    }

    @DeleteMapping("/{classId}/members/{userId}")
    @Operation(summary = "移除班级成员")
    @PreAuthenticated
    public CommonResult<String> removeMember(
            @Parameter(description = "班级ID", required = true, example = "1") @PathVariable("classId") Long classId,
            @Parameter(description = "用户ID", required = true, example = "2") @PathVariable("userId") Long targetUserId) {
        Long currentUserId = getLoginUserId();
        log.info("移除班级成员，班级ID: {}, 目标用户ID: {}, 操作用户ID: {}", classId, targetUserId, currentUserId);

        classService.removeMember(classId, targetUserId, currentUserId);
        return success("成员移除成功");
    }

    @GetMapping("/{classId}/assignments")
    @Operation(summary = "获取班级作业列表")
    @PreAuthenticated
    public CommonResult<List<cn.iocoder.yudao.module.reading.controller.app.assignment.vo.AssignmentRespVO>> getClassAssignments(
            @Parameter(description = "班级ID", required = true, example = "1") @PathVariable("classId") Long classId) {
        Long userId = getLoginUserId();
        log.info("获取班级作业列表，班级ID: {}, 用户ID: {}", classId, userId);

        List<cn.iocoder.yudao.module.reading.controller.app.assignment.vo.AssignmentRespVO> result = assignmentService.getClassAssignments(classId, userId);
        return success(result);
    }

    @GetMapping("/{classId}/punch-records")
    @Operation(summary = "获取班级打卡记录")
    @PreAuthenticated
    public CommonResult<List<PunchRecordRespVO>> getClassPunchRecords(
            @Parameter(description = "班级ID", required = true, example = "1") @PathVariable("classId") Long classId) {
        Long userId = getLoginUserId();
        log.info("获取班级打卡记录，班级ID: {}, 用户ID: {}", classId, userId);

        List<PunchRecordRespVO> result = classService.getClassPunchRecords(classId, userId);
        return success(result);
    }

    @PostMapping("/{classId}/punch")
    @Operation(summary = "班级打卡")
    @PreAuthenticated
    public CommonResult<String> classPunch(
            @Parameter(description = "班级ID", required = true, example = "1") @PathVariable("classId") Long classId,
            @Valid @RequestBody ClassPunchReqVO punchReqVO) {
        Long userId = getLoginUserId();
        log.info("班级打卡，班级ID: {}, 用户ID: {}, 请求参数: {}", classId, userId, punchReqVO);

        classService.classPunch(classId, userId, punchReqVO);
        return success("打卡成功");
    }

    @PostMapping("/switch")
    @Operation(summary = "切换当前班级")
    @PreAuthenticated
    public CommonResult<String> switchClass(@Valid @RequestBody SwitchClassReqVO switchReqVO) {
        Long userId = getLoginUserId();
        log.info("切换当前班级，用户ID: {}, 请求参数: {}", userId, switchReqVO);

        classService.switchCurrentClass(userId, switchReqVO);
        return success("班级切换成功");
    }

    // =============================================
    // 缺失接口补充
    // =============================================

    @GetMapping("/generate-code")
    @Operation(summary = "生成班级口令")
    @PreAuthenticated
    public CommonResult<String> generateClassCode() {
        Long userId = getLoginUserId();
        log.info("生成班级口令，用户ID: {}", userId);

        String classCode = classService.generateClassCode();
        return success(classCode);
    }

    @GetMapping("/verify-code/{code}")
    @Operation(summary = "验证班级口令")
    @PreAuthenticated
    public CommonResult<ClassCodeVerifyRespVO> verifyClassCode(
            @Parameter(description = "班级口令", required = true, example = "208506115") @PathVariable("code") String code) {
        Long userId = getLoginUserId();
        log.info("验证班级口令，用户ID: {}, 班级口令: {}", userId, code);

        ClassCodeVerifyRespVO result = classService.verifyClassCode(code);
        return success(result);
    }

    @PostMapping("/{classId}/transfer")
    @Operation(summary = "转让班级管理权")
    @PreAuthenticated
    public CommonResult<String> transferClass(
            @Parameter(description = "班级ID", required = true, example = "1") @PathVariable("classId") Long classId,
            @Valid @RequestBody TransferClassReqVO transferReqVO) {
        Long userId = getLoginUserId();
        log.info("转让班级管理权，班级ID: {}, 用户ID: {}, 请求参数: {}", classId, userId, transferReqVO);

        classService.transferClass(classId, userId, transferReqVO);
        return success("班级管理权转让成功");
    }

    @PutMapping("/{classId}/lock")
    @Operation(summary = "锁定/解锁班级")
    @PreAuthenticated
    public CommonResult<String> lockClass(
            @Parameter(description = "班级ID", required = true, example = "1") @PathVariable("classId") Long classId,
            @Valid @RequestBody LockClassReqVO lockReqVO) {
        Long userId = getLoginUserId();
        log.info("锁定/解锁班级，班级ID: {}, 用户ID: {}, 请求参数: {}", classId, userId, lockReqVO);

        classService.lockClass(classId, userId, lockReqVO);
        return success(lockReqVO.getIsLocked() ? "班级锁定成功" : "班级解锁成功");
    }

    @GetMapping("/users/{userId}/punch-records")
    @Operation(summary = "获取成员打卡记录")
    @PreAuthenticated
    public CommonResult<List<PunchRecordRespVO>> getUserPunchRecords(
            @Parameter(description = "用户ID", required = true, example = "1") @PathVariable("userId") Long targetUserId) {
        Long currentUserId = getLoginUserId();
        log.info("获取成员打卡记录，目标用户ID: {}, 当前用户ID: {}", targetUserId, currentUserId);

        // TODO: 实现获取成员打卡记录的逻辑
        // 这个接口应该在用户模块中实现，这里只是临时占位
        return success(new ArrayList<>());
    }

}
